#include "onexplayerstickcontrol.h"
#ifdef _WIN32
#include <conio.h>
#include <Windows.h>
#include <mmsystem.h>
#include <mainwindow.h>
#endif
#define   CENTRE_NUM 32767

#define   ZERO_BASE 4915


#pragma comment(lib,"Winmm.lib")

OneXPlayerStickControl::OneXPlayerStickControl(QObject *parent):
    StickControl(parent)
{
    connect(&m_Timer,&QTimer::timeout,this,&OneXPlayerStickControl::onTimeOut);
    m_Timer.start(40);
    m_vtHotKeys.push_back({JOY_BUTTON1,STICK_KEY1,"A"});
    m_vtHotKeys.push_back({JOY_BUTTON2,STICK_KEY2,"B"});
    m_vtHotKeys.push_back({JOY_BUTTON3,STICK_KEY3,"X"});
    m_vtHotKeys.push_back({JOY_BUTTON4,STICK_KEY4,"Y"});
    m_vtHotKeys.push_back({JOY_BUTTON5,STICK_KEY5,"LB"});
    m_vtHotKeys.push_back({JOY_BUTTON6,STICK_KEY6,"RB"});
    m_vtHotKeys.push_back({JOY_BUTTON7,STICK_KEY7,"BACK"});
    m_vtHotKeys.push_back({JOY_BUTTON8,STICK_KEY8,"START"});
    m_vtHotKeys.push_back({JOY_POVLEFT,STICK_KEY11,"左"});
    m_vtHotKeys.push_back({JOY_POVFORWARD,STICK_KEY12,"上"});
    m_vtHotKeys.push_back({JOY_POVRIGHT,STICK_KEY13,"右"});
    m_vtHotKeys.push_back({JOY_POVBACKWARD,STICK_KEY14,"下"});
}

void OneXPlayerStickControl::onTimeOut()
{
#ifdef _WIN32
    JOYINFOEX joyinfoex;
    joyinfoex.dwSize=sizeof (JOYINFOEX);
    joyinfoex.dwFlags=JOY_RETURNALL;
    UINT joyNums;
    joyNums=joyGetNumDevs();
    if(joyNums>=1)
    {
        MMRESULT joy=joyGetPosEx(JOYSTICKID1,&joyinfoex);

        if(joy==JOYERR_NOERROR)
        {
            if(dwXpos != joyinfoex.dwXpos)
            {
                int nRange = (int)joyinfoex.dwXpos<CENTRE_NUM?(CENTRE_NUM - ZERO_BASE):(CENTRE_NUM + ZERO_BASE);
                float x = ((int)joyinfoex.dwXpos-nRange)*1.0/nRange;
                if(abs(x) < 0.01)  x = 0;
                else if(x > 1)  x  = 1;
                else if(x < -1)  x = -1;
                emit xChanged(x);
                dwXpos = joyinfoex.dwXpos;
            }
            if(dwYpos != joyinfoex.dwYpos)
            {
                int nRange = (int)joyinfoex.dwYpos<CENTRE_NUM?(CENTRE_NUM - ZERO_BASE):(CENTRE_NUM + ZERO_BASE);
                float y = ((int)joyinfoex.dwYpos-nRange)*1.0/nRange;
                if(abs(y) < 0.01)  y = 0;
                else if(y > 1)  y  = 1;
                else if(y < -1)  y = -1;
                emit yChanged(y);
                dwYpos = joyinfoex.dwYpos;
            }
            if(dwUpos != joyinfoex.dwUpos)
            {
                int nRange = (int)joyinfoex.dwUpos<CENTRE_NUM?(CENTRE_NUM - ZERO_BASE):(CENTRE_NUM + ZERO_BASE);
                float u = ((int)joyinfoex.dwUpos-nRange)*1.0/nRange;
                if(abs(u) < 0.01)  u = 0;
                else if(u > 1)  u  = 1;
                else if(u < -1)  u = -1;
                emit uChanged(u);
                dwUpos = joyinfoex.dwUpos;
            }
            if(dwRpos != joyinfoex.dwRpos)
            {
                int nRange = (int)joyinfoex.dwRpos<CENTRE_NUM?(CENTRE_NUM - ZERO_BASE):(CENTRE_NUM + ZERO_BASE);
                float r = ((int)joyinfoex.dwRpos-nRange)*1.0/nRange;
                if(abs(r) < 0.01)  r = 0;
                else if(r > 1)  r  = 1;
                else if(r < -1)  r = -1;
                emit rChanged(r);
                dwRpos = joyinfoex.dwRpos;
            }
            if(dwZpos != joyinfoex.dwZpos)
            {
                int nRange = (int)joyinfoex.dwZpos<CENTRE_NUM?(CENTRE_NUM - ZERO_BASE):(CENTRE_NUM + ZERO_BASE);
                float z = ((int)joyinfoex.dwZpos-nRange)*1.0/nRange;
                if(abs(z) < 0.01)  z = 0;
                else if(z > 1)  z  = 1;
                else if(z < -1)  z = -1;
                emit zChanged(z);
                dwZpos = joyinfoex.dwZpos;
            }
            if(dwPOV != joyinfoex.dwPOV)
            {
                int povKeys[] = {JOY_POVFORWARD,JOY_POVRIGHT,JOY_POVBACKWARD,JOY_POVLEFT};
                for (int i = 0; i < 4; ++i)
                {
                    if (dwPOV != povKeys[i] && joyinfoex.dwPOV == povKeys[i])
                    {
                        FUNCTION_KEY funcKey = FUNCTION_KEY_NONE;

                        // if((joyinfoex.dwButtons&JOY_BUTTON5) >0)
                        // {
                        //     funcKey = FUNCTION_KEY1;
                        // }
                        // else if((joyinfoex.dwButtons&JOY_BUTTON6) >0)
                        // {
                        //     funcKey = FUNCTION_KEY2;
                        // }
                        qDebug()<<"keypressed:"<<povKeys[i];
                        emit keyPressed(funcKey,getUserKeyBySysKey(povKeys[i]));
                    }
                }
                dwPOV = joyinfoex.dwPOV;
            }
            if(dwButtons != joyinfoex.dwButtons)
            {
                int buttons[] = {JOY_BUTTON1,JOY_BUTTON2,JOY_BUTTON3,JOY_BUTTON4,JOY_BUTTON5,JOY_BUTTON6,JOY_BUTTON7,JOY_BUTTON8,JOY_BUTTON9,JOY_BUTTON10};
                int nLen = sizeof(buttons)/sizeof(int);
                for (int i = 0; i < nLen; ++i)
                {
                    if ((joyinfoex.dwButtons & buttons[i]) >0 && (dwButtons & buttons[i]) == 0)
                    {
                        FUNCTION_KEY funcKey = FUNCTION_KEY_NONE;

                        // if((joyinfoex.dwButtons&JOY_BUTTON5) >0)
                        // {
                        //     funcKey = FUNCTION_KEY1;
                        // }
                        // else if((joyinfoex.dwButtons&JOY_BUTTON6) >0)
                        // {
                        //     funcKey = FUNCTION_KEY2;
                        // }
                        qDebug()<<"keypressed:"<<buttons[i];
                        emit keyPressed(funcKey,getUserKeyBySysKey(buttons[i]));
                    }
                }
                dwButtons = joyinfoex.dwButtons;
            }
        }
    }
#endif
}


QString OneXPlayerStickControl::getFuncKeyName(FUNCTION_KEY nKey)
{
    switch(nKey)
    {
    case FUNCTION_KEY1:
        return "LB";
    case FUNCTION_KEY2:
        return "RB";
    default:
        return "undefine";
    }
}

QString OneXPlayerStickControl::getHotKeyName(STICK_KEY nKey)
{
    QString strKey = "undefine";
    for(int i = 0; i < m_vtHotKeys.size(); ++i)
    {
        if(m_vtHotKeys[i].nUserKey == nKey)
        {
            strKey = m_vtHotKeys[i].strKeyName;
            break;
        }
    }
    return strKey;
}


STICK_KEY OneXPlayerStickControl::getUserKeyBySysKey(int nKey)
{
    STICK_KEY nUserKey = STICK_KEY_NONE;
    for(int i = 0; i < m_vtHotKeys.size(); ++i)
    {
        if(m_vtHotKeys[i].nSysKey == nKey)
        {
            nUserKey = m_vtHotKeys[i].nUserKey;
            break;
        }
    }
    return nUserKey;
}
